﻿import sdk from '../core/index';
import { DataEquip, Item } from "../shared/face/index";
import { ItemType, quality } from "../shared/face/enums";
import SkillManager from "../core/rpg/skill/SkManager";
import EquipManage, { EquipTemplate } from "../core/manage/EquipManage";
import { config, configKey } from "../config";
import { DataSkill } from "../shared/face";
import { Skill, SkillData } from '../core/rpg/types';
import { BaseServiceClass } from './BaseServiceClass';
import { ServiceInstance } from './base/index';

/**
 * 装备服务类 - 统一管理所有装备相关的业务逻辑
 * 职责：
 * 1. 装备的创建、使用、穿戴、卸下
 * 2. 装备的强化、附魔等功能
 * 3. 装备的属性计算和技能处理
 * 4. 装备的转换（装备<->道具）
 */
export class EquipService extends BaseServiceClass implements ServiceInstance {
    /** 强化增长系数（每级+10%） */
    static readonly STRENGTHEN_GROWTH_COEFF = 1.1;
    /** 强化衰减系数（每级-3%） */
    static readonly STRENGTHEN_DECAY_COEFF = 0.97;
    /** 强化属性乘数 = (增长系数^n) * (衰减系数^n) */
    getStrengthenMultiplier(level: number): number {
        const n = Math.max(0, level || 0);
        // n 最低为 1 的业务在其他处约束，这里容错从 0 开始
        return Math.pow(EquipService.STRENGTHEN_GROWTH_COEFF, n) * Math.pow(EquipService.STRENGTHEN_DECAY_COEFF, n);
    }
    /**
     * 根据当前强化等级计算概率
     * 成功率 = 1 / n
     * 失败率 = 1 / (3n + 1)（乘以调整系数0.8）
     * 不变率 = 1 - 成功率 - 失败率（若出现负值则按 0 处理）
     * 为保证和为100%，按“先占成功，再分配失败，剩余为不变”的顺序归一。
     */
getStrengthenRates(n: number): { success: number; fail: number; none: number } {
        const level = Math.max(1, Math.floor(n || 1));
        const successRaw = 1 / level;
        const failRaw = (1 / (3 * level + 1)) * 0.5; // 保留用户对失败率的0.8调整
        // 当成功率达到或超过1时，其余概率为0
        if (successRaw >= 1) {
            return { success: 1, fail: 0, none: 0 };
        }
        const remain = Math.max(0, 1 - successRaw);
        const fail = Math.min(failRaw, remain);
        const none = Math.max(0, remain - fail);
        return { success: successRaw, fail, none };
    }
    /**
     * 执行一次强化判定并直接修改装备强化等级（最低保底为 1 级）
     */
tryStrengthen(equip: DataEquip): {
        result: 'success' | 'fail' | 'none';
        beforeLevel: number;
        afterLevel: number;
        rates: { success: number; fail: number; none: number };
    } {
        const before = Math.max(1, Math.floor(equip.strengthenLevel || 1));
        const rates = this.getStrengthenRates(before);
        const r = Math.random();
        let result: 'success' | 'fail' | 'none';
        if (r < rates.success) {
            result = 'success';
            equip.strengthenLevel = before + 1;
        } else if (r < rates.success + rates.fail) {
            result = 'fail';
            equip.strengthenLevel = Math.max(1, before - 1);
        } else {
            result = 'none';
            equip.strengthenLevel = before;
        }
        equip.updateTime = Date.now();
        return { result, beforeLevel: before, afterLevel: equip.strengthenLevel, rates };
    }
    
    /**
     * 计算进化成功率： (1 / 目标品质) / 2
     * 目标品质 = 当前品质 + 1
     * 若已达上限 SSR，则不可进化
     */
getEvolveSuccessRate(currentQuality: quality): number {
        if (currentQuality >= quality.SSR) return 0;
        const target = currentQuality + 1;
        return (1 / target) / 2;
    }
    /**
     * 尝试进化：成功则品质+1，重置属性（参考 createEquipAttribute），并将强化等级重置为1；失败不变
     */
tryEvolve(equip: DataEquip): {
        canEvolve: boolean;
        success: boolean;
        beforeQuality: quality;
        afterQuality: quality;
        successRate: number;
    } {
        const beforeQ = equip.quality;
        if (beforeQ >= quality.SSR) {
            return { canEvolve: false, success: false, beforeQuality: beforeQ, afterQuality: beforeQ, successRate: 0 };
        }
        const successRate = this.getEvolveSuccessRate(beforeQ);
        const roll = Math.random();
        if (roll < successRate) {
            const newQ = (beforeQ + 1) as quality;
            equip.quality = newQ;
            // 重置属性：沿用 ModernPropService 的 createEquipAttribute 逻辑
            // 重置强化等级为 1
            equip.attribute = sdk.prop.createEquipAttribute(equip.sys, equip.type, equip.job, equip.solt_type, newQ);
            equip.updateTime = Date.now();
            return { canEvolve: true, success: true, beforeQuality: beforeQ, afterQuality: newQ, successRate };
        } else {
            return { canEvolve: true, success: false, beforeQuality: beforeQ, afterQuality: beforeQ, successRate };
        }
    }
    
    /**
     * 创建装备实例
     * @param templateId 装备模板ID
     * @returns 装备实例
     */
    static createEquip(templateId: string): DataEquip | null {
        const template = sdk.equip.getTemplateById(templateId);
        if (!template) {
            console.error(`装备模板不存在: ${templateId}`);
            return null;
        }
        
        // 使用PropManage创建装备
        const item = sdk.prop.createProp({
            type: ItemType.装备,
            id: templateId,
            count: 1
        });
        
        return item.data as DataEquip;
    }
    
    /**
     * 装备转换为道具
     * @param equip 装备对象
     * @returns 道具对象
     */
equipToItem(equip: DataEquip): Item {
        return sdk.prop.cover_equipToItem(equip);
    }
    
    /**
     * 道具转换为装备
     * @param item 道具对象
     * @returns 装备对象
     */
itemToEquip(item: Item): DataEquip | null {
        if (item.type !== ItemType.装备) {
            console.error('道具类型不是装备');
            return null;
        }
        
        return item.data as DataEquip;
    }
    
    /**
     * 计算装备的属性值
     * @param equip 装备对象
     * @param attributeKey 属性键
     * @returns 属性值
     */
getEquipAttribute(equip: DataEquip, attributeKey: string): number {
        const base = sdk.tool.common.getCfgAttributeVal(equip.attribute, attributeKey);
        const n = Math.max(0, Math.floor(equip.strengthenLevel || 0));
        if (n <= 0) {
            return base;
        }
        const multiplier = this.getStrengthenMultiplier(n);
        return base * multiplier;
    }
    
    /**
     * 计算装备栏的总属性值
     * @param equipList 装备列表
     * @param attributeKey 属性键
     * @returns 总属性值
     */
getTotalAttribute(equipList: DataEquip[], attributeKey: string): number {
        let totalValue = 0;
        equipList.forEach(equip => {
            totalValue += this.getEquipAttribute(equip, attributeKey);
        });
        return totalValue;
    }
    
    /**
     * 获取装备的技能列表
     * @param equip 装备对象
     * @returns 技能列表
     */
getEquipSkills(equip: DataEquip): any[] {
        if (!equip.skill || equip.skill.length === 0) {
            return [];
        }
        
        return equip.skill.map(skillUse => {
            const skill = SkillManager.getSkillById(skillUse.skillId);
            return {
                ...skill,
                reName: skillUse.reName
            };
        });
    }
    
    /**
     * 检查装备是否可以穿戴
     * @param equip 装备对象
     * @param currentEquipList 当前装备列表
     * @returns 是否可以穿戴
     */
canEquip(equip: DataEquip, currentEquipList: DataEquip[]): boolean {
        // 检查是否有相同类型的装备
        const existingEquip = currentEquipList.find(e => e.solt_type === equip.solt_type);
        
        // 如果有相同类型的装备，需要先卸下
        if (existingEquip) {
            console.log(`已有相同类型装备: ${existingEquip.name}`);
        }
        
        return true; // 总是可以穿戴，只是会替换现有装备
    }
    
    /**
     * 穿戴装备
     * @param equip 要穿戴的装备
     * @param currentEquipList 当前装备列表
     * @returns 穿戴结果
     */
equipItem(equip: DataEquip, currentEquipList: DataEquip[]): {
        success: boolean;
        message: string;
        replacedEquip?: DataEquip;
        newEquipList: DataEquip[];
    } {
        const newEquipList = [...currentEquipList];
        const existingIndex = newEquipList.findIndex(e => e.solt_type === equip.solt_type);
        
        if (existingIndex !== -1) {
            // 替换现有装备
            const replacedEquip = newEquipList[existingIndex];
            newEquipList[existingIndex] = equip;
            
            return {
                success: true,
                message: `已替换装备${replacedEquip.name}为${equip.name}`,
                replacedEquip: replacedEquip,
                newEquipList: newEquipList
            };
        } else {
            // 添加新装备
            newEquipList.push(equip);
            
            return {
                success: true,
                message: `已穿戴装备${equip.name}`,
                newEquipList: newEquipList
            };
        }
    }
    
    /**
     * 卸下装备
     * @param equipIndex 装备索引
     * @param currentEquipList 当前装备列表
     * @returns 卸下结果
     */
unequipItem(equipIndex: number, currentEquipList: DataEquip[]): {
        success: boolean;
        message: string;
        unequippedEquip?: DataEquip;
        newEquipList: DataEquip[];
    } {
        if (equipIndex < 0 || equipIndex >= currentEquipList.length) {
            return {
                success: false,
                message: '装备不存在',
                newEquipList: currentEquipList
            };
        }
        
        const newEquipList = [...currentEquipList];
        const unequippedEquip = newEquipList.splice(equipIndex, 1)[0];
        
        return {
            success: true,
            message: `已卸下装备:${unequippedEquip.name}`,
            unequippedEquip: unequippedEquip,
            newEquipList: newEquipList
        };
    }
    
    /**
     * 获取装备的显示名称（包含附魔等级）
     * @param equip 装备对象
     * @returns 显示名称
     */
getDisplayName(equip: DataEquip): string {
        let displayName = equip.name;
        
        // TODO: 如果有附魔等级，显示附魔等级
        // if (equip.enchantLevel && equip.enchantLevel > 0) {
        //     displayName = `${displayName} +${equip.enchantLevel}`;
        // }
        
        return displayName;
    }
    
    /**
     * 获取装备的详细描述
     * @param equip 装备对象
     * @returns 详细描述
     */
getDetailedDescription(equip: DataEquip): string {
        let description = equip.desc;
        
        // 添加属性信息
        if (equip.attribute && equip.attribute.length > 0) {
            description += '\n属性:\n';
            equip.attribute.forEach(attr => {
                description += `  ${attr.key}: +${attr.val}\n`;
            });
        }
        
        // 添加技能信息
        if (equip.skill && equip.skill.length > 0) {
            description += '\n技能:\n';
            equip.skill.forEach(skillUse => {
                const skill = SkillManager.getSkillById(skillUse.skillId);
                if (skill) {
                    const skillName = skillUse.desc || skillUse.reName || skill.name;
                    description += `  ${skillName}: ${skill.desc}\n`;
                }
            });
        }
        
        return description;
    }

    /**
     * 通过模板ID获取装备模板（实例方法，供DI调用者使用）
     */
    getTemplateById(templateId: string): EquipTemplate | undefined {
        return sdk.equip.getTemplateById(templateId);
    }

    /**
     * 获取随机装备模板ID（实例方法，供DI调用者使用）
     */
    getRandomTemplateId(): string {
        return sdk.equip.getRandomTemplateId();
    }

    /**
     * 获取随机装备模板（实例方法，供DI调用者使用）
     */
    getRandomTemplate(): EquipTemplate | undefined {
        return sdk.equip.getRandomTemplate();
    }

    /**
     * 获取装备可附魔的技能列表
     * @param equip 装备对象
     * @returns 可附魔的技能列表
     */
    getEnchantableSkills(equip: DataEquip): any[] {
        // 从配置中获取对应装备类型的技能配置
        const equipConfigs = config.get(configKey.配置_装备属性) as Map<string, any>;
 

        // 查找匹配的装备配置
        const matchingConfigs = Array.from(equipConfigs.values()).filter(equipConfig => 
            equipConfig.sys === equip.sys && 
            equipConfig.type === equip.type && 
            equipConfig.job === equip.job && 
            equipConfig.solt === equip.solt_type
        );

        if (matchingConfigs.length === 0) {
            return [];
        }

        const equipConfig = matchingConfigs[0];
        const availableSkills: any[] = [];

        // 将origionSk中的数据填充到skill[index]，但只填充skill[index]中没有的字段
        for (let index = 0; index < equipConfig.origionSk.length; index++) {
            const skillItem = equipConfig.skill[index] || {};
            const originItem = equipConfig.origionSk[index];
            // const skillData = SkillManager.getSkillById(originItem.skillId) as Skill;
            let itemData:DataSkill = {
                skillId: skillItem.skillId || originItem.skillId,
                reName: skillItem.reName || undefined,
                desc: skillItem.desc || '',
                level: skillItem.level || originItem.level,
                maxLevel: skillItem.maxLevel || originItem.maxLevel,
            }
            availableSkills.push(itemData);
        }
        // 合并原始技能和自定义技能
        // if (equipConfig.origionSk && Array.isArray(equipConfig.origionSk)) {
        //     availableSkills.push(...equipConfig.origionSk);
        // }
        // if (equipConfig.skill && Array.isArray(equipConfig.skill)) {
        //     availableSkills.push(...equipConfig.skill);
        // }

        // 过滤掉装备已有的技能
        const existingSkillIds = equip.skill.map(s => s.skillId);
        return availableSkills.filter(skill => !existingSkillIds.includes(skill.skillId));
    }

    /**
     * 计算附魔成功率
     * @param equip 装备对象
     * @returns 成功率 (0-1)
     */
    getEnchantSuccessRate(equip: DataEquip): number {
        const existingSkillCount = equip.skill.length;
        if (existingSkillCount === 0) {
            return 1.0; // 没有技能时100%成功
        }
        return 1 / existingSkillCount;
    }

    /**
     * 执行附魔
     * @param equip 装备对象
     * @returns 附魔结果
     */
    tryEnchant(equip: DataEquip): {
        success: boolean;
        message: string;
        addedSkill?: any;
        beforeSkillCount: number;
        afterSkillCount: number;
        successRate: number;
    } {
        const beforeSkillCount = equip.skill.length;
        const successRate = this.getEnchantSuccessRate(equip);
        
        // 随机判定是否成功
        if (Math.random() > successRate) {
            return {
                success: false,
                message: '附魔失败，装备没有获得新技能',
                beforeSkillCount,
                afterSkillCount: beforeSkillCount,
                successRate
            };
        }

        // 获取可附魔的技能
        const availableSkills = this.getEnchantableSkills(equip);
        if (availableSkills.length === 0) {
            return {
                success: false,
                message: '没有可附魔的技能',
                beforeSkillCount,
                afterSkillCount: beforeSkillCount,
                successRate
            };
        }

        // 随机选择一个技能
        const randomIndex = Math.floor(Math.random() * availableSkills.length);
        const selectedSkill = availableSkills[randomIndex];

        // 再次检查是否与现有技能重复（双重保险）
        const existingSkillIds = equip.skill.map(s => s.skillId);
        if (existingSkillIds.includes(selectedSkill.skillId)) {
            return {
                success: false,
                message: '附魔失败，随机出的技能与装备现有技能重复',
                beforeSkillCount,
                afterSkillCount: beforeSkillCount,
                successRate
            };
        }

        // 创建新的技能数据
        const newSkill: DataSkill = {
            skillId: selectedSkill.skillId,
            reName: selectedSkill.reName,
            desc: selectedSkill.desc,
            level: 1,
            maxLevel: selectedSkill.maxLevel || 1,
            cooldown: selectedSkill.cooldown,
            permanentBoosts:{},
            useCount: 0
        };

        // 添加到装备
        equip.skill.push(newSkill);
        equip.updateTime = Date.now();

        return {
            success: true,
            message: `附魔成功！装备获得了新技能: ${newSkill.reName || newSkill.skillId}`,
            addedSkill: newSkill,
            beforeSkillCount,
            afterSkillCount: equip.skill.length,
            successRate
        };
    }

    /**
     * 获取装备可升级的技能列表
     * @param equip 装备对象
     * @returns 可升级的技能列表
     */
    getUpgradeableSkills(equip: DataEquip): DataSkill[] {
        if (!equip.skill || equip.skill.length === 0) {
            return [];
        }

        return equip.skill.filter(skill => {
            const currentLevel = skill.level || 1;
            const maxLevel = skill.maxLevel || 10;
            return currentLevel < maxLevel;
        });
    }

    /**
     * 升级装备技能
     * @param equip 装备对象
     * @param skillId 技能ID
     * @returns 升级结果
     */
upgradeEquipSkill(equip: DataEquip, skillId: string): {
        success: boolean;
        message: string;
        skill?: DataSkill;
        beforeLevel: number;
        afterLevel: number;
    } {
        if (!equip.skill || equip.skill.length === 0) {
            return {
                success: false,
                message: '装备没有技能',
                beforeLevel: 0,
                afterLevel: 0
            };
        }

        const skillIndex = equip.skill.findIndex(s => s.skillId === skillId);
        if (skillIndex === -1) {
            return {
                success: false,
                message: '技能不存在',
                beforeLevel: 0,
                afterLevel: 0
            };
        }

        const skill = equip.skill[skillIndex];
        const beforeLevel = skill.level || 1;
        const maxLevel = skill.maxLevel || 10;

        // 检查是否可以升级
        if (beforeLevel >= maxLevel) {
            return {
                success: false,
                message: '技能已达到最大等级',
                beforeLevel,
                afterLevel: beforeLevel
            };
        }

        // 直接提升一级
        const afterLevel = beforeLevel + 1;
        skill.level = afterLevel;
        equip.updateTime = Date.now();

        const skillName = skill.reName || skill.skillId;

        return {
            success: true,
            message: `${skillName}升级成功！${beforeLevel}级 -> ${afterLevel}级`,
            skill,
            beforeLevel,
            afterLevel
        };
    }

    /**
     * 获取装备技能升级成功率
     * @param equip 装备对象
     * @param skillId 技能ID
     * @returns 升级成功率（固定100%，因为装备技能升级总是成功）
     */
getSkillUpgradeSuccessRate(equip: DataEquip, skillId: string): number {
        if (!equip.skill || equip.skill.length === 0) {
            return 0;
        }

        const skill = equip.skill.find(s => s.skillId === skillId);
        if (!skill) {
            return 0;
        }

        const currentLevel = skill.level || 1;
        const maxLevel = skill.maxLevel || 10;

        // 如果已达到最大等级，返回0%
        if (currentLevel >= maxLevel) {
            return 0;
        }

        // 装备技能升级总是100%成功
        return 1.0;
    }

    /**
     * 初始化服务
     */
    async init(): Promise<void> {
        this.log('info', 'EquipService initializing...');
        // 装备服务初始化逻辑（如果需要的话）
        this.log('info', 'EquipService initialized successfully');
    }

    /**
     * 销毁服务
     */
    async destroy(): Promise<void> {
        this.log('info', 'EquipService destroying...');
        // 清理资源
        this.log('info', 'EquipService destroyed successfully');
    }

    /**
     * 获取服务名称
     */
    getServiceName(): string {
        return 'EquipService';
    }

    /**
     * 检查服务是否就绪
     */
    isReady(): boolean {
        return true;
    }
}

// 导出单例实例以保持向后兼容
export const equipService = new EquipService(); 
